fix(BOP-274): port Rust parity fixes into Solidity mocks #140
Open
stevieraykatz wants to merge 5 commits into
Open
fix(BOP-274): port Rust parity fixes into Solidity mocks #140stevieraykatz wants to merge 5 commits into
stevieraykatz wants to merge 5 commits into
Conversation
Rust precompile enforces MINT_RECEIVER_POLICY unconditionally on every mint, including factory-originated mints in the bootstrap window. The Solidity mock previously bypassed the check whenever `_isPrivileged()` held, which let initCalls mint to non-authorized accounts. Drop the bypass so the mock matches Rust semantics. An unconfigured slot still reads as ALWAYS_ALLOW_ID, so default-deploy bootstrap flows are unaffected.
…rap (BOP-274) Rust precompile enforces the "target account must be blocked under TRANSFER_SENDER_POLICY" guard unconditionally on burnBlocked. The Solidity mock previously bypassed the check whenever `_isPrivileged()` held. Drop the bypass so factory-originated burnBlocked calls during the bootstrap window also revert AccountNotBlocked unless the target is actually blocked, matching Rust.
…OP-274) The Rust precompile exposes an is_announcement_active runtime flag that flips true for the lifetime of an announce(...) bracket and false at all other times. The Solidity mock did not surface the same view, leaving inner-call contracts no way to detect they were executing inside a disclosed corp action. Add the IB20Asset.isAnnouncementActive() interface entry and back it in MockB20Asset with an EIP-1153 transient bool set at the top of announce and cleared at the bottom. Transient storage auto-clears at tx end, so a revert anywhere in the bracket cannot leave the flag stuck true.
Interface Coverage✅ All interface functions have test coverage. |
📊 Forge Coverage (
|
| File | Lines | Stmts | Branches | Funcs |
|---|---|---|---|---|
| 🟢 B20FactoryLib.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockActivationRegistry.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockActivationRegistryStorage.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockB20.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockB20Asset.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟡 MockB20Factory.sol | 98.95% | 99.08% | 100.00% | 100.00% |
| 🟢 MockB20Stablecoin.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockB20Storage.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockPolicyRegistry.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| 🟢 MockPolicyRegistryStorage.sol | 100.00% | 100.00% | 100.00% | 100.00% |
| Total | 99.86% | 99.88% | 100.00% | 100.00% |
Full report: download artifact. To browse locally: make coverage (runs forge coverage + genhtml + opens the HTML report).
✅ Fork tests: all 602 passedbase/base is fully in sync with the base-std spec. |
stevieraykatz
commented
Jun 3, 2026
The previous commit added an isAnnouncementActive() view backed by an EIP-1153 transient flag, aiming for parity with the Rust precompile's is_announcement_active runtime flag. On review the check is unnecessary: inner-call dispatch in announce(...) is self-delegatecall only, so there is no reentrancy surface for an external contract to want to detect a bracket-in-progress against. Removes the view from IB20Asset, the flag and its set/clear from MockB20Asset.announce, and the boundary tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings two Solidity-mock behaviors back into parity with the Rust precompile after Roger flagged the divergences:
_mintno longer skipsMINT_RECEIVER_POLICYwhen called from the factory bootstrap window. Rust enforces the policy unconditionally; the policy itself defaults toALWAYS_ALLOW_IDfor an unconfigured slot, so existing bootstrap flows are unaffected.burnBlockedno longer skips the "target is blocked" check during bootstrap. Same shape as the mint fix: unconditional enforcement, default-allow when unconfigured.The third subtask (
is_announcement_activeview) was explored but dropped —announce(...)only self-delegatecalls, so there is no external reentrancy surface that would want to detect a bracket-in-progress.Linear: BOP-274.
Test plan
forge buildcleanforge test— 607 tests pass, no regressions